/**
 * Copyright (C)  2011  chen wei hua.
 * Permission is granted to copy, distribute and/or modify this document
 * under the terms of the GNU Free Documentation License, Version 2.0
 * or any later version published by the Free Software Foundation;
 * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 * A copy of the license is included in the section entitled "GNU Free Documentation License".
 */
package com.javaeye.store.service;

import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.javaeye.accounting.dao.MaterialsMonthBatchDetailDAO;
import com.javaeye.accounting.dto.MaterialsMonthBatchDetail;
import com.javaeye.store.dao.MaterialsBatchDetailDAO;
import com.javaeye.store.dao.MaterialsDAO;
import com.javaeye.store.dao.MaterialsSKUDetailDAO;
import com.javaeye.store.dto.Materials;
import com.javaeye.store.dto.MaterialsBatchDetail;
import com.javaeye.store.dto.MaterialsFieldCustom;
import com.javaeye.store.dto.MaterialsSKUDetail;
import com.javaeye.common.util.DAOUtil;
import com.javaeye.common.util.DateUtils;
import com.javaeye.common.util.ListUtil;
import com.javaeye.common.web.PageInfo;

public class MaterialsService implements IMaterialsService {
	
	private static Log log = LogFactory.getLog(MaterialsService.class);
	
	private MaterialsDAO dao;
	
	private MaterialsBatchDetailDAO materialsBatchDetailDao;
	
	private MaterialsMonthBatchDetailDAO materialsMonthBatchDetailDao;
	
	private MaterialsSKUDetailDAO materialsSKUDetailDao;
	
	public void setDao(MaterialsDAO dao) {
		this.dao = dao;
	}

	public void setMaterialsBatchDetailDao(MaterialsBatchDetailDAO materialsBatchDetailDao) {
		this.materialsBatchDetailDao = materialsBatchDetailDao;
	}

	public void setMaterialsMonthBatchDetailDao(
			MaterialsMonthBatchDetailDAO materialsMonthBatchDetailDao) {
		this.materialsMonthBatchDetailDao = materialsMonthBatchDetailDao;
	}

	public void setMaterialsSKUDetailDao(MaterialsSKUDetailDAO materialsSKUDetailDao) {
		this.materialsSKUDetailDao = materialsSKUDetailDao;
	}

	public List<Materials> getAutoCompleteMaterials(String name, int size) {
		List<Materials> results = dao.getAutoCompleteMaterials(name, size);
		if (results == null || results.size() == 0) {
			log.warn("在数据库中未找到物料数据");
		}
		return results;
	}
	
	/**
	 * 通过编码取得在库品
	 * @param code 在库品编码
	 * @return 在库品
	 */
	public Materials getMaterialsByCode(String code) {
		Materials materials = dao.getMaterialsByCode(code);
		if (materials == null) {
			log.warn("在数据库中未找到指定的物料  code：" + code);
		}
		return materials;
	}
	
	/**
	 * 取得在库品的实时库存数量
	 * @param code 在库品编码
	 * @return 实时库存数量
	 */
	/*public double getCurrentAtStroeNumber(String code) {
		return dao.getCurrentAtStroeNumber(code);
	}*/

	/**
	 * 通过自动生成ID取得在库品,
	 * @param code ID
	 * @return 在库品
	 */
	@Override
	public Materials getMaterials(String materialsId) {
		int intId = Integer.parseInt(materialsId);
		Materials materials = dao.getMaterials(intId);
		if (materials == null) {
			log.warn("在数据库中未找到指定的物料  id：" + materialsId);
		}
		return materials;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Materials> getMaterialsList(Materials condition, PageInfo pageInfo) {
		List results = dao.getPageData(condition, pageInfo);
		if (results == null || results.size() == 0) {
			log.warn("在数据库中未找到物料数据");
		}
		return results;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<Materials> getMaterialsExportList(Materials condition) {
		List results = dao.getMaterialsExportList(condition);
		if (results == null || results.size() == 0) {
			log.warn("在数据库中未找到物料数据");
		}
		return results;
	}

	@Override
	public boolean removeMaterials(String materialsId) {
		int intId = Integer.parseInt(materialsId);
		dao.removeMaterials(intId);
		return true;
	}

	@Override
	public boolean saveMaterials(String materialsId, Materials materials) {
		if (materialsId != null && !"".equals(materialsId)) {
			//更新
			final Materials dbMaterials = dao.getMaterials(Integer.parseInt(materialsId));
			dbMaterials.setCode(materials.getCode());
			dbMaterials.setRootCategory(materials.getRootCategory());
			dbMaterials.setCategory(materials.getCategory());
			dbMaterials.setName(materials.getName());
			dbMaterials.setType(materials.getType());
			dbMaterials.setUnits(materials.getUnits());
			dbMaterials.setProperty(materials.getProperty());
			
			DAOUtil.mergeDataSet(dbMaterials.getSkuDetails(), materials.getSkuDetails(),
					new DAOUtil.SameObjectable() {
				
						public void addObject(Object o) {
							MaterialsSKUDetail element = (MaterialsSKUDetail)o;
							dbMaterials.addSkuDetail(element);
						}
						
						public void setValues(Object dbo, Object pageo) {
							//MaterialsSKUDetail dbElement = (MaterialsSKUDetail)dbo;
							//MaterialsSKUDetail pageElement = (MaterialsSKUDetail)pageo;
							
						}
						
						@SuppressWarnings("unchecked")
						public void removeObject(Iterator i, Object o) {
							MaterialsSKUDetail element = (MaterialsSKUDetail)o;
							element.setInuse(0);
						}
						
						public boolean isSameObject(Object o1, Object o2) {
							MaterialsSKUDetail detail1 = (MaterialsSKUDetail)o1;
							MaterialsSKUDetail detail2 = (MaterialsSKUDetail)o2;
							return (detail1.getFieldCombox().equals(detail2.getFieldCombox())
									&& detail1.getInuse() == detail2.getInuse());
						}
					});
			DAOUtil.mergeDataSet(dbMaterials.getCustomFields(), materials.getCustomFields(),
					new DAOUtil.SameObjectable() {
				
						public void addObject(Object o) {
							MaterialsFieldCustom element = (MaterialsFieldCustom)o;
							dbMaterials.addCustomField(element);
						}
						
						@SuppressWarnings("unchecked")
						public void removeObject(Iterator i, Object o) {
							//MaterialsFieldCustom element = (MaterialsFieldCustom)o;
							//element.setInuse(0);
						}
						
						public void setValues(Object dbo, Object pageo) {
							MaterialsFieldCustom dbElement = (MaterialsFieldCustom)dbo;
							MaterialsFieldCustom pageElement = (MaterialsFieldCustom)pageo;
							dbElement.setValue(pageElement.getValue());
						}
						
						public boolean isSameObject(Object o1, Object o2) {
							MaterialsFieldCustom detail1 = (MaterialsFieldCustom)o1;
							MaterialsFieldCustom detail2 = (MaterialsFieldCustom)o2;
							return (detail1.getFieldId().equals(detail2.getFieldId())
									&& detail1.getInuse() == detail2.getInuse());
						}
					});
			dao.saveMaterials(dbMaterials);
		} else {
			Materials dbMaterials = dao.getMaterialsByCode(materials.getCode());
			if (dbMaterials != null) {
				return false;
			}
			dao.saveMaterials(materials);
		}
		return true;
	}
	
	public void saveImportMaterials(List<Object[]> materials) {
		for (Object[] data : materials) {
			int skuId = (Integer)data[1];
			materialsMonthBatchDetailDao.removeDetail(skuId);
			materialsBatchDetailDao.removeDetail(skuId);
		}
		int oldSkuId = -1; 
		for (Object[] data : materials) {
			int category = (Integer)data[0];
			int skuId = (Integer)data[1];
			String batchNo = (String)data[2];
			double price = (Double)data[3];
			float number = (Float)data[4];
			float defectiveNumber = (Float)data[5];
			
			MaterialsSKUDetail skuDetail = materialsSKUDetailDao.getMaterialsSKUDetail(skuId);
			if (skuDetail == null) {
				log.warn("导入数据时在数据库中未找到在库品, skuId=" + skuId);
				continue;
			}
			if (oldSkuId != skuId) {
				skuDetail.setNumber(number);
				skuDetail.setDefectiveNumber(defectiveNumber);
			} else {
				skuDetail.setNumber(skuDetail.getNumber() + number);
				skuDetail.setDefectiveNumber(skuDetail.getDefectiveNumber() + defectiveNumber);
			}
			materialsSKUDetailDao.saveMaterialsSKUDetail(skuDetail);
			
			//初始化期初库存数
			String monthNo = DateUtils.formatString(DateUtils.getBeforeMonthEndDate(), "yyyy-MM");
			MaterialsMonthBatchDetail monthDetail = 
				materialsMonthBatchDetailDao.getMaterialsMonthBatchDetail(skuId, batchNo, monthNo);
			if (monthDetail == null) {
				monthDetail = new MaterialsMonthBatchDetail();
				monthDetail.setSkuDetail(skuDetail);
				monthDetail.setBatchNo(batchNo);
				monthDetail.setMonthNo(monthNo);
				monthDetail.setPrice(price);
			}
			if (oldSkuId != skuId) {
				monthDetail.setNumber(number);
				monthDetail.setDefectiveNumber(defectiveNumber);
			} else {
				monthDetail.setNumber(monthDetail.getNumber() + number);
				monthDetail.setDefectiveNumber(monthDetail.getDefectiveNumber() + defectiveNumber);
			}
			materialsMonthBatchDetailDao.saveMaterialsMonthBatchDetail(monthDetail);
			
			//更新批次库存数量
			MaterialsBatchDetail batchDetail = materialsBatchDetailDao.getBatchDetail(skuId, batchNo);
			if (batchDetail == null) {
				batchDetail = new MaterialsBatchDetail();
				batchDetail.setMaterialsId(skuId);
				batchDetail.setBatchNo(batchNo);
			}
			if (ListUtil.checkIsProcurementCategory(category)) {
				//合格品入库数量(原料)
				batchDetail.setInNumber(number);
				//不合格品入库数量(原料)
				batchDetail.setPlanNumber(defectiveNumber);
				batchDetail.setType(MaterialsBatchDetail.MATERIALS_BATCH_TYPE_MATERIALS);
			} else {
				//合格入库数量(成品)
				batchDetail.setNumber(number);
			}
			batchDetail.setPrice(price);
			materialsBatchDetailDao.save(batchDetail);
			
			oldSkuId = skuId;
		}
	}
}
